package ru.compscicenter.databases.zaikina.common;

import java.io.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import org.json.simple.JSONAware;

public abstract class IOProcessor<DataItem extends JSONAware> {

    private static final String IdValueSeparator = "__//__";

    protected abstract DataItem parseItem(String str);
    
    
    public HashMap<Integer, DataItem> loadObjectsFromDump(String file) {
        HashMap<Integer, DataItem> items = new HashMap<Integer, DataItem>();
        BufferedReader reader = getReader(file);

        if (reader == null) {
            return items;
        }

        String line;
        try {
            while((line = reader.readLine()) != null) {
                String[] args = line.split(IdValueSeparator);
                if (args.length == 2) {
                    items.put(Integer.parseInt(args[0]), parseItem(args[1]));
                }
            }
            reader.close();
        } catch (IOException ex) {
            return items;
        }
        return items;
    }

    private BufferedReader getReader(String file) {
        BufferedReader reader;
        try {
            reader = new BufferedReader(new FileReader(file));
        } catch (FileNotFoundException ex) {
            return null;
        }
        return reader;
    }

    private PrintWriter getWriter(String file) {
        PrintWriter writer;
        try {
            writer = new PrintWriter(new FileWriter(file));
        } catch (IOException ex) {
            return null;
        }
        return writer;
    }

    public HashMap<String, ArrayList<Integer>> loadHashFromDump(String file) {
        HashMap<String, ArrayList<Integer>> map = new HashMap<String, ArrayList<Integer>>();
        BufferedReader reader = getReader(file);

        if (reader == null) {
            return map;
        }
        String line;

        try {
            while((line = reader.readLine()) != null) {
                if (line.length() > 0) {
                    String[] arr = line.split(" ");
                    if (arr.length > 1) {
                        if (!map.containsKey(arr[0])) {
                            map.put(arr[0], new ArrayList<Integer>());
                        }
                        for (int i = 1; i < arr.length; ++i) {
                            map.get(arr[0]).add(Integer.parseInt(arr[i]));
                        }
                    }
                }
            }
            reader.close();
        } catch (IOException ex) {
            return map;
        }
        return map;
    }

    public void writeObjectsToDump(String file, HashMap<Integer, DataItem> items) {
        PrintWriter writer;
        if ((writer = getWriter(file)) == null)
            return;

        for (Map.Entry<Integer, DataItem> item : items.entrySet()) {
            writer.println(item.getKey() + IdValueSeparator + item.getValue().toJSONString());
        }
        writer.close();
    }

    public void writeHashToDump(String file, HashMap<String, ArrayList<Integer>> map) {
        PrintWriter writer;
        if ((writer = getWriter(file)) == null)
            return;

        for (String item : map.keySet()) {
            String line = item;
            for (Integer id : map.get(item)) {
                line += (" " + id);
            }
            writer.println(line);
        }
        writer.close();
    }

    public int readVersion(String file) {
        BufferedReader reader;
        if ((reader = getReader(file)) == null) {
            return 0;
        }

        int result;
        try {
            result = reader.read();
            reader.close();
        } catch (IOException ex) {
            return 0;
        }
        return result;
    }

    public void writeVersion(String file, int num) {
        PrintWriter writer;
        if ((writer = getWriter(file)) == null)
            return;

        writer.print((char)num);
        writer.close();
    }
}
